home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
libs
/
intuisup.lha
/
Intuisup
/
source.lha
/
Gadgets
/
gadgets4.asm
< prev
next >
Wrap
Assembly Source File
|
1992-07-11
|
8KB
|
252 lines
* $Revision Header *** Header built automatically - do not edit! **********
*
* (C) Copyright 1991 by Torsten Jürgeleit
*
* Name .....: gadgets4.asm
* Created ..: Thursday 19-Dec-91 21:34:12
* Revision .: 1
*
* Date Author Comment
* ========= ==================== ====================
* 01-Jul-92 Torsten Jürgeleit corrected slider bug -> sometimes
* clicking inside of slider gadget
* container don't move the knob
* inside of slider gadget container
* 19-Dec-91 Torsten Jürgeleit Created this file!
*
***************************************************************************
*
* Proportional gadget support routines (32 bit !!!)
*
* $Revision Header ********************************************************
*---------------------------------------------------------------------------
* USHORT calc_prop_body(ULONG max_num, ULONG size)
* d0.w d0.l d1.l
* Calculate the body value for the PropInfo structure
*---------------------------------------------------------------------------
XDEF _calc_prop_body
_calc_prop_body:
movem.l d2-d6,-(sp)
; --- check max_num
move.l d0,d6 ; save max_num in d6
beq cpb_maximum ; max_num == 0 ?
cmp.l d0,d1 ; size >= max_num ?
bhs cpb_maximum
; --- multiply size [32 bit] by MAXBODY ($ffff) [16 bit] with 48 bit arithmetic
moveq #0,d0 ; clear shift out reg for size
move.l d1,d3 ; init result by doing the first add
moveq #0,d2 ; clear shift out reg of result
moveq #16-2,d4 ; init shift count (MAXBODY has only 16 bits - one add already done)
cpb_mul_loop:
; --- shift size
add.l d1,d1 ; shift left of size
addx.w d0,d0 ; save shift out
; --- inc result
add.l d1,d3 ; add shifted size to result
addx.w d0,d2 ; add shift out and carry
dbra d4,cpb_mul_loop
; --- divide result [48 bit] by max_num [32 bit] with 48 bit arithmetic
moveq #0,d0 ; clear result
moveq #0,d1 ; clear shift out reg for divident
moveq #0,d4 ; clear sub divisor help reg
moveq #32-1,d5 ; init shift count
cpb_div_loop:
; --- shift result and divident
add.l d0,d0 ; shift result
add.l d3,d3 ; shift left of lower LONG of divident
addx.l d2,d2 ; shift left of upper LONG of divident - add shift out
addx.w d1,d1 ; save shift out
; --- check if upper LONG of divident large enough to sub divisor from
tst.w d1 ; any shift out ?
bne cpb_sub_divisor
cmp.l d2,d6 ; upper LONG of divident > divisor ?
bhi cpb_next_div
cpb_sub_divisor:
sub.l d6,d2 ; sub divisor from upper LONG of divident
subx.w d4,d1 ; sub underflow (d4 = 0) from shift out of upper LONG of divident
addq.l #1,d0 ; set bit 0 of result
cpb_next_div:
dbra d5,cpb_div_loop
; --- don't return ZERO as prop_body
tst.w d0
bne cpb_exit
moveq #1,d0
cpb_exit:
movem.l (sp)+,d2-d6
rts
cpb_maximum:
move.l #$ffff,d0 ; prop_body := MAXBODY
bra cpb_exit
*---------------------------------------------------------------------------
* USHORT calc_prop_pot(ULONG max_num, ULONG size, ULONG num)
* d0.w d0.l d1.l d2.l
* Calculate the prop value for the PropInfo structure
*---------------------------------------------------------------------------
XDEF _calc_prop_pot
_calc_prop_pot:
movem.l d3-d6,-(sp)
; --- prepare max_num
move.l d0,d6 ; save max_num
beq cpp_minimum
sub.l d1,d6 ; max_num -:= size
bcs cpp_minimum
; --- multiply num [32 bit] by MAXPOT ($ffff) [16 bit] with 48 bit arithmetic
moveq #0,d0 ; clear shift out reg for size
move.l d2,d1 ; init num
move.l d1,d3 ; init result by doing the first add
moveq #0,d2 ; clear shift out reg of result
moveq #16-2,d4 ; init shift count (MAXPOT has only 16 bits - one add already done)
cpp_mul_loop:
; --- shift num
add.l d1,d1 ; shift left of num
addx.w d0,d0 ; save shift out
; --- inc result
add.l d1,d3 ; add shifted num to result
addx.w d0,d2 ; add shift out and carry
dbra d4,cpp_mul_loop
ext.l d2 ; expand upper WORD to LONG
; --- divide result [48 bit] by (max_num - size) [32 bit] with 48 bit arithmetic
moveq #0,d0 ; clear result
moveq #0,d1 ; clear shift out reg for divident
moveq #0,d4 ; clear sub divisor help reg
moveq #32-1,d5 ; init shift count
cpp_div_loop:
; --- shift result and divident
add.l d0,d0 ; shift result
add.l d3,d3 ; shift left of lower LONG of divident
addx.l d2,d2 ; shift left of upper LONG of divident - add shift out
addx.w d1,d1 ; save shift out
; --- check if upper LONG of divident large enough to sub divisor from
tst.w d1 ; any shift out ?
bne cpp_sub_divisor
cmp.l d2,d6 ; upper LONG of divident > divisor ?
bhi cpp_next_div
cpp_sub_divisor:
sub.l d6,d2 ; sub divisor from upper LONG of divident
subx.w d4,d1 ; sub underflow (d4 = 0) from shift out of upper LONG of divident
addq.l #1,d0 ; set bit 0 of result
cpp_next_div:
dbra d5,cpp_div_loop
; --- if pot_value > MAXPOT then return MAXPOT
cmp.l #$ffff,d0
bls cpp_exit
move.l #$ffff,d0 ; prop_pot := MAXPOT
cpp_exit:
movem.l (sp)+,d3-d6
rts
cpp_minimum:
moveq #0,d0 ; prop_pot := 0
bra cpp_exit
*---------------------------------------------------------------------------
* ULONG get_prop_pos(ULONG max_num, ULONG size, UWORD pot_value)
* d0.l d0.l d1.l d2.w
* Calculate the position of the knob of a proporitional gadget
*---------------------------------------------------------------------------
XDEF _get_prop_pos
_get_prop_pos:
movem.l d3-d6,-(sp)
; --- prepare max_num
sub.l d1,d0 ; max_num -:= size
bcs gpp_minimum
; --- if pot_value ]0..MAXPOT[ then inc pot_value and max_num
move.w d2,d6 ; save pot value
beq gpp_minimum ; pot_value == 0 ?
addq.w #1,d6 ; inc pot_value
bcs gpp_exit ; if pot_value == MAXPOT then return (max_num - size)
; --- multiply (max_num - size) [32 bit] by pot_value [16 bit] with 48 bit arithmetic
moveq #0,d1 ; clear shift out reg for max_num
moveq #0,d3 ; clear result
moveq #0,d2 ; clear shift out reg of result
moveq #0,d4 ; reset bit count
moveq #16-1,d5 ; init shift count (16 bits from pot_value)
bra gpp_check_bit
gpp_mul_loop:
add.l d0,d0 ; shift left of max_num
addx.w d1,d1 ; save shift out
gpp_check_bit:
; --- check bit of pot_value
btst d4,d6
beq gpp_next_mul ; bit set ?
; --- if bit set then inc result
add.l d0,d3 ; add shifted max_num to result
addx.w d1,d2 ; add shift out and carry
gpp_next_mul:
addq.w #1,d4 ; inc bit count
dbra d5,gpp_mul_loop
ext.l d2 ; expand upper WORD to LONG
; --- divide result [48 bit] by MAXPOT ($ffff) [16 bit] with 48 bit arithmetic
moveq #0,d0 ; clear result
moveq #0,d1 ; clear shift out reg for divident
moveq #0,d4 ; clear sub divisor help reg
moveq #32-1,d5 ; init shift count
move.l #$ffff,d6 ; init divisor (MAXPOT)
gpp_div_loop:
; --- shift result and divident
add.l d0,d0 ; shift result
add.l d3,d3 ; shift left of lower LONG of divident
addx.l d2,d2 ; shift left of upper LONG of divident - add shift out
addx.w d1,d1 ; save shift out
; --- check if upper LONG of divident large enough to sub divisor from
tst.w d1 ; any shift out ?
bne gpp_sub_divisor
cmp.l d2,d6 ; upper LONG of divident > divisor ?
bhi gpp_next_div
gpp_sub_divisor:
sub.l d6,d2 ; sub divisor from upper LONG of divident
subx.w d4,d1 ; sub underflow (d4 = 0) from shift out of upper LONG of divident
addq.l #1,d0 ; set bit 0 of result
gpp_next_div:
dbra d5,gpp_div_loop
gpp_exit:
movem.l (sp)+,d3-d6
rts
gpp_minimum:
moveq #0,d0 ; prop_pos := 0
bra gpp_exit
END